import React, { useEffect, useRef, useState } from "react"; // 添加useState导入
import * as THREE from "three";
import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

// 定义动作类型
type ActionType = "idle" | "沮丧"  | "运动" | "打招呼";

interface ThreeAvatarProps {
  currentAction?: ActionType; // 添加动作prop
}

const MODEL_PATH = "/modules/shuzi.glb"; // 模型文件路径
const WIDTH = 800; // 画布宽度
const HEIGHT = 800; // 画布高度

/**
* ThreeAvatar 组件用于渲染一个带有动画的3D角色。
*
* @param ThreeAvatarProps - 组件属性
* @param currentAction - 当前角色动作，可选参数，默认为 "idle"。
* @returns 返回一个渲染了3D角色的React元素。
*/

const ThreeAvatar: React.FC<ThreeAvatarProps> = ({
  currentAction = "idle",
}) => {
  // 接收动作prop
  const mountRef = useRef<HTMLDivElement>(null);
  // 添加动画状态管理ref
  const mixerRef = useRef<THREE.AnimationMixer | null>(null);
  // 动画列表ref
  const animationsRef = useRef<THREE.AnimationClip[]>([]);
  // 当前动作ref
  const currentActionRef = useRef<THREE.AnimationAction | null>(null);
  
  useEffect(() => {
    // 初始化3D场景、相机、渲染器等
    let mixer: THREE.AnimationMixer | null = null;
    // 添加动画播放逻辑ref
    let frameId: number;
    // 创建场景
    const scene = new THREE.Scene();

    // 更新相机宽高比
    const camera = new THREE.PerspectiveCamera(45, WIDTH / HEIGHT, 0.1, 1000);
    camera.position.set(0, 1.5, 3);

    // 启用alpha透明通道
    const renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true });
    renderer.setSize(WIDTH, HEIGHT); // 应用新尺寸
    // 应用渲染器到div元素中
    if (mountRef.current) {
      // 应用渲染器到div元素中
      mountRef.current.appendChild(renderer.domElement);
    }

    // 添加轨道控制器实现自由旋转
    const controls = new OrbitControls(camera, renderer.domElement);
    controls.enableDamping = true; // 启用阻尼效果
    controls.dampingFactor = 0.05; // 设置阻尼系数
    controls.enableZoom = true; // 启用缩放功能
    controls.zoomSpeed = 0.5; // 设置缩放速度
    controls.minDistance = 2; // 设置最小缩放距离
    controls.maxDistance = 10; // 设置最大缩放距离
    controls.enablePan = false; // 禁用平移

    // 灯光
    const light = new THREE.DirectionalLight(0xffffff, 1);
    // 调整光源位置
    light.position.set(0, 5, 5);
    // 添加光源到场景中
    scene.add(light);
    // 添加环境光
    scene.add(new THREE.AmbientLight(0xffffff, 0.5));

    // 加载FBX模型
    const loader = new GLTFLoader();
    loader.load(
      MODEL_PATH,
      (gltf) => {
        // 修改模型加载逻辑以支持动画播放
        const object = gltf.scene;
        // 保留现有模型居中与缩放逻辑
        const box = new THREE.Box3().setFromObject(object);
        // 居中并缩放模型 
        const size = new THREE.Vector3();
        // 计算模型尺寸
        box.getSize(size);
        // 居中模型
        const center = new THREE.Vector3();
        // 计算模型中心
        box.getCenter(center);
        // 移动模型到中心位置
        object.position.sub(center);
        // 缩放模型到合适大小
        const scale = Math.min(1.5 / size.x, 2.5 / size.y, 1.5 / size.z);
        // 应用缩放比例并再次居中模型

        object.scale.setScalar(scale * 2);
        // 重新计算包围盒和中心
        const newBox = new THREE.Box3().setFromObject(object);
        const newCenter = new THREE.Vector3();
        newBox.getCenter(newCenter);
        object.position.sub(newCenter); // 再次居中
        scene.add(object);

        // 相机根据模型高度调整
        const modelHeight = newBox.max.y - newBox.min.y;
        camera.position.set(0, modelHeight * 0.2, modelHeight * 2.2);
        camera.lookAt(0, 0, 0);
        // 修改动画加载逻辑以支持多动画
        if (gltf.animations && gltf.animations.length > 0) {
          animationsRef.current = gltf.animations;
          mixerRef.current = new THREE.AnimationMixer(object);
          // 添加调试日志
          console.log('模型动画数量:', gltf.animations.length);
          gltf.animations.forEach((anim, index) => {
            console.log(`动画${index}:`, anim.name);
          });
          // 存储动画名称映射表 - 需要根据实际shuzi.glb中的动画名称调整
          const actionMap: Record<string, number> = {
            idle: 0, // 默认动画
            沮丧: 1, // 假设沮丧动画是第二个动画
            运动: 2, // 假设运动动画是第四个动画
            打招呼: 3, // 假设打招呼动画是第五个动画
          };
          // 播放当前选择的动画
          const actionIndex = actionMap[currentAction] || 0;
          currentActionRef.current = mixerRef.current.clipAction(
            gltf.animations[actionIndex]
          );
          currentActionRef.current.play();
        }
      },
      undefined,
      (error: any) => {
        // eslint-disable-next-line no-console
        console.error("FBX模型加载失败", error);
      }
    );

    // 动画播放逻辑
    const animate = () => {
      frameId = requestAnimationFrame(animate);
      if (mixerRef.current) mixerRef.current.update(0.016); // 使用ref中的mixer实例
      controls.update();
      renderer.render(scene, camera);
    };
    animate();
    // 清理逻辑

    return () => {
      cancelAnimationFrame(frameId);
      renderer.dispose();
      controls.dispose();
      if (
        mountRef.current &&
        renderer.domElement.parentNode === mountRef.current
      ) {
        mountRef.current.removeChild(renderer.domElement);
      }
    };
  }, []);
  // 添加动作变化监听effect
  useEffect(() => {
    if (
      !mixerRef.current ||
      animationsRef.current.length === 0 ||
      !currentAction
    )
      return;
    // 更新动作映射表，确保与实际模型动画名称匹配
    const actionMap: Record<string, number> = {
      idle: 0,
      沮丧: 1,
      运动: 2,
      打招呼: 3
    };
    // 切换动作
    const actionIndex = actionMap[currentAction] || 0;
    console.log(`切换到动作: ${currentAction}, 索引: ${actionIndex}`);
    // 检查索引是否有效
    if (actionIndex >= animationsRef.current.length) {
      console.error(`动画索引${actionIndex}不存在，当前动画数量: ${animationsRef.current.length}`);
      return;
    }
    // 获取新动作
    const newAction = mixerRef.current.clipAction(
      animationsRef.current[actionIndex]
    );

    // 停止当前动作并播放新动作
    if (currentActionRef.current) {
      currentActionRef.current.stop();
    }
    // 存储新动作
    newAction.play();
    currentActionRef.current = newAction;
  }, [currentAction]);

  // 更新容器尺寸
  return <div ref={mountRef} style={{ width: WIDTH, height: HEIGHT }} />;
};

export default ThreeAvatar;
